//
//  HFSmartLink.m
//  SmartlinkLib
//
//  Created by wangmeng on 15/3/16.
//  Copyright (c) 2015年 HF. All rights reserved.
//

#import "HFSmartLink.h"
#import "UdpProxy.h"

#define SMTV30_BASELEN      76
#define SMTV30_STARTCODE      '\r'
#define SMTV30_STOPCODE       '\n'

static HFSmartLink * me = nil;

@implementation HFSmartLink{
    SmartLinkProcessBlock processBlock;
    SmartLinkSuccessBlock successBlock;
    SmartLinkFailBlock failBlock;
    SmartLinkStopBlock stopBlock;
    SmartLinkEndblock endBlock;
    NSString * pswd;
    BOOL isconnnecting;
    BOOL userStoping;
    NSInteger sendTime;
    NSMutableDictionary *deviceDic;
}

+(instancetype)shareInstence{
    if(me==nil){
        me = [[HFSmartLink alloc]init];
    }
    return me;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        /**
         *  初始化 套接字
         */
        [UdpProxy shaInstence];
        deviceDic = [[NSMutableDictionary alloc]init];
        self.waitTimers = 15;
    }
    return self;
}

-(void)startWithKey:(NSString *)key processblock:(SmartLinkProcessBlock)pblock successBlock:(SmartLinkSuccessBlock)sblock failBlock:(SmartLinkFailBlock)fblock endBlock:(SmartLinkEndblock)eblock{
    
    pswd = key;
    processBlock = pblock;
    successBlock = sblock;
    failBlock = fblock;
    endBlock = eblock;
    sendTime = 0;
    userStoping = false;
    [deviceDic removeAllObjects];
    if(isconnnecting){
        failBlock(@"is connecting ,please stop frist!");
        return ;
    }
    isconnnecting = true;
    //开始配置线程
    [[[NSOperationQueue alloc]init]addOperationWithBlock:^(){
        [self connect];
    }];
}


-(void)stopWithBlock:(SmartLinkStopBlock)block{
    stopBlock = block;
    isconnnecting = false;
    userStoping = true;
}
-(void)closeWithBlock:(SmartLinkCloseBlock)block{
    if(isconnnecting){
        dispatch_async(dispatch_get_main_queue(), ^(){
            block(@"please stop connect frist",false);
        });
    }
    if([UdpProxy shaInstence]){
        [[UdpProxy shaInstence] close];
        dispatch_async(dispatch_get_main_queue(), ^(){
            block(@"close Ok",true);
        });
    }else{
        dispatch_async(dispatch_get_main_queue(), ^(){
            block(@"udp sock is Closed,on need Close more",false);
        });
    }
}

#pragma Send and Rcv

-(void)connect{
    while (isconnnecting && sendTime <= 3) {
        
        for (int i = 0; i<200&&isconnnecting; i++) {
            [self sendOnePackageByLen:SMTV30_BASELEN];
            usleep(10000);
        }
        
        for (int i = 0; i<3&&isconnnecting; i++) {
            [self sendOnePackageByLen:SMTV30_BASELEN+SMTV30_STARTCODE];
            usleep(50000);
        }
        
        for (int i = 0; i<pswd.length&&isconnnecting; i++) {
             NSInteger code=SMTV30_BASELEN+ [pswd characterAtIndex:i];
            [self sendOnePackageByLen:code];
            usleep(50000);
        }
        
        for (int i = 0 ; i<3&&isconnnecting; i++) {
            [self sendOnePackageByLen:SMTV30_BASELEN+SMTV30_STOPCODE];
            usleep(50000);
        }
        
        for (int i = 0; i<3&&isconnnecting; i++) {
            [self sendOnePackageByLen:SMTV30_BASELEN+pswd.length+256];
            usleep(50000);
        }
        sendTime++;
        NSLog(@"send time %ld",(long)sendTime);
        dispatch_async(dispatch_get_main_queue(), ^(){
            processBlock(sendTime);
        });
    }
    
    //开始接收线程
    [[[NSOperationQueue alloc]init]addOperationWithBlock:^(){
        [self recvNewModule];
    }];
    
    NSLog(@"start waitting module msg ");
    NSInteger waitCount = 0;
    while (waitCount < self.waitTimers&&isconnnecting){
        [[UdpProxy shaInstence]send:"smartlinkfind"];
       
        sleep(1);
        waitCount++;
        dispatch_async(dispatch_get_main_queue(), ^(){
            processBlock(sendTime-1+waitCount);
        });
    }
    isconnnecting = false;
    
    dispatch_async(dispatch_get_main_queue(), ^(){
        processBlock(18);
    });
}

-(void)sendOnePackageByLen:(NSInteger)len{
    char data[len+1];
    memset(data, 5, len);
    data[len]='\0';
    [[UdpProxy shaInstence] send:data];
}
-(void)recvNewModule{
    while (isconnnecting) {
        HFSmartLinkDeviceInfo * dev = [[UdpProxy shaInstence] recv];
        if(dev == nil){
            continue;
        }
        
        if([deviceDic objectForKey:dev.mac] != nil){
            continue;
        }

        [deviceDic setObject:dev forKey:dev.mac];
        
        dispatch_async(dispatch_get_main_queue(), ^(){
            successBlock(dev);
        });
        
        if (self.isConfigOneDevice) {
            isconnnecting = false;
            dispatch_async(dispatch_get_main_queue(), ^(){
                endBlock(deviceDic);
            });
            return ;
        }
    }
    
    if(userStoping){
        dispatch_async(dispatch_get_main_queue(), ^(){
            stopBlock(@"stop connect ok",true);
        });
    }
    
    if(deviceDic.count <= 0){
        dispatch_async(dispatch_get_main_queue(), ^(){
            failBlock(@"smartLink fail ,no device is configed");
        });
    }
    
    [[UdpProxy shaInstence] close];
    
    dispatch_async(dispatch_get_main_queue(), ^(){
        endBlock(deviceDic);
    });
}

@end
